lseek() & creat() [system call]

커서 조정 및 새로 생성
lseek()
함수의 seek pointer(커서)를 조정하는 함수이다.
조정된 seek pointer는 파일의 read/write 시 사용
특정 위치부터 읽거나 쓰고 싶을 때 사용

파일을 처음 열면 seek poisition은 0이다.
O_APPEND 플래그를 주어 열게되면 최초의 seek position은 파일의 끝에 있다.
#include <unistd.h>
#includee <sys/types.h>
off_t lseek(int fd, off_t offset, int whence);
fd: 조정할 파일의 파일 디스크립터
offset: 기준점으로부터 이동할 거리
whence: 기준점
    SEEK_SET(0): 파일의 맨 앞
    SEEK_CUR(1): 현재 seek 포인터
    SEEK_END(2): 파일의 맨 끝

return value: 성공 시, 위치한 Seek pointer
                      실패 시, -1 리턴후 errno 설정
creat() <fcntl.h>
파일을 생성, 이미 같은 이름의 파일이 있다면 파일의 내용을 모두 삭제하고 열기를 한다.
int creat(const char* file, mode_t mode);
file: 경로명 포함 파일 전체 이름
mode: 생성할 파일의 접근 권한

return value: 파일 디스크립터
creat() & open()
creat("./test.txt", 0644);
open(".//test.txt", O_WRONLY|O_CREAT|O_TRUNC, 0644);
open이 creat의 상위 호환이다. open() 함수보다 creat()는 옵션이 고정되어 있어서 매우 제한적이며,
creat()는 쓰기만 가능하기 때문에 읽기까지 가능하게 할려면 close() 다음에 open()을 다시해야 하기 때문에 open() 함수를 사용하는
것이 더 좋다.
lseek_test1.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(void){
char *fname="lseek_test.txt";
int fd;
off_t fsize;
if((fd=open(fname, O_RDONLY))<0){
fprintf(stderr, "open error for %s\n", fname);
exit(1);
}
if((fsize=lseek(fd, 0, SEEK_END))<0){
fprintf(stderr, "lseek error\n");
exit(1);
}
printf("The size of <%s> is %lld bytes.\n", fname, fsize);
exit(0);
}

csian@Csianui-MacBookPro linux % ./lseek_test1

The size of <lseek_test.txt> is 30 bytes.

lseek_test2.c(hole file)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <gcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
// , , ,
#define CREAT_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
char buf1[]="1234567890";
char buf2[]="ABCDEFGHIJ";
int main(void){
char *fname="lseek_test.txt";
int fd;
if((fd=creat(fname, CREAT_MODE))<0){
fprintf(stderr, "creat error for %s\n", fname);
exit(1)
}
if(write(fd, buf1, 12)!=12){
fprintf(stderr, "buf1 write error\n");
exit(1);
}
if(lseek(fd, 15000, SEEK_SET)<0){
fprintf(stderr, "lseek error\n");
exit(1);
}
if(write(fd, buf2, 12)!=12){
fprintf(stderr, "buf2 write error\n");
exit(1);
}
exit(0);
}
lseek_test3.c (STDIN FILE 입력으로 받기)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, const char* argv[])
{
if(lseek(STDIN_FILEDNO, 0, SEEK_CUR)==-1)fprintf(stderr, "cannot seek!\n");
else printf("seek OK!\n");
return 0;
}
$./lseek_test3 < lseek_test.txt
seek OK!
hole_file.c
#include <unistd.h>
#include <fcntl.h>
int main(void){
int fd;
//"holefile"
fd=creat("holefile", 0644);
//5byte "hello"
write(fd, "hello", 5);
// 10 )
lseek(fd, 10, SEEK_CUR);
write(fd, "hello", 5);
// 8192 byte 8kb(2*4096) set
lseek(fd, 8192, SEEK_SET);
write(fd, "bye", 3);
close(fd);
return 0;
}

csian@Csianui-MacBookPro linux % du -h holefile

 12K holefile

8KB가 초과되서 12KB가 사용된 모습